﻿using System;
using System.Collections;
using System.Xml;
using System.Text;
using System.Web;
using InfoJetSoft.Service.Entity;
using InfoJetSoft.Service.Util;
using InfoJetSoft.Service.EscapeRule;

namespace InfoJetSoft.Service.Worker
{
	
	class FormBuildXMLDocByFieldListWorker
	{
		
		public static void  buildXMLDocByFieldList(Form form)
		{
			foreach( Field field in form.FieldList )
			{
				if( field.Name.IndexOf( "@" ) > 0 )
				{
					field.Value = field.Value.Replace( "\n", "&#xA;" );
					field.Value = field.Value.Replace( "\"", "&quot;" );
					field.Value = field.Value.Replace( "'", "&#39;" );
				}
			}

            //CID 0749 //2011.09.01 //Begin
            if (form.Command.Equals(JetConstant.CMD_UPDATE_AddSignature))
            {
                string xml = form.ParamTable["xdoc_param_dsig_xml"] as string;
                //CID 1022 //2011.10.16 //Begin
                XmlDocument xmlDoc = DOMUtil.buildDocPreserveWhitespace(System.Text.Encoding.UTF8.GetBytes(xml));
                //CID 1022 //2011.10.16 //End
			
                form.XmlDoc = xmlDoc;
                form.XmlNsResolver = new NamespaceResolver(xmlDoc);

                //刷新Id,其中没有Id.
                FormBuildFieldListByXMLDocWorker.buildFieldListByXMLDoc(form, false);
            }
            else
            {
                //CID 0664 //2010.10.06 //Begin
                XmlDocument xmlDoc = null;
                if (form.Manifest.FormFieldsCacheEnabled)
                {
                    string xml = FormSession.restoreFormXml(form);
                    //CID 1022 //2011.10.16 //Begin
                    xmlDoc = DOMUtil.buildDocPreserveWhitespace(System.Text.Encoding.UTF8.GetBytes(xml));
                    //CID 1022 //2011.10.16 //End
                    string valueChangeId = (string)form.ParamTable[JetConstant.XDOC_PARAM_UPDATE_ID];
                    if (valueChangeId != null && valueChangeId.Length > 0)
                    {
                        //CID 0664 //2010.11.28 //if
                        if (!valueChangeId.StartsWith("_s_"))
                        {
                            XmlNode targetNode = DOMUtil.findNodeByJetId(xmlDoc, valueChangeId);
                            form.CachedOldValue = DOMUtil.getNodeValue(targetNode);
                        }
                    }
                    foreach (Field field in form.FieldList)
                    {
                        if (field.JetId.StartsWith("_0_"))
                        {
                            XmlNode targetNode = DOMUtil.findNodeByJetId(xmlDoc, field.JetId);
                            //CID 0664 //2010.11.24 //Begin
                            if (field.IsRichText)
                            {
                                targetNode.InnerXml = field.Value;
                            }
                            else
                            {
                                DOMUtil.setNodeValue(targetNode, field.Value);
                            }
                            //CID 0664 //2010.11.24 //End
                        }
                    }
                }
                else
                {
                    StringBuilder xmlBuffer = new StringBuilder();
                    xmlBuffer.Append("<?xml version='1.0' encoding='UTF-8'?>");
                    buildPI(form.PiFieldList, xmlBuffer);
                    if (!buildElementOrText(form.FieldList, new int[] { 0 }, xmlBuffer))
                    {
                        throw new InfoJetException("Build XML failure by paramters.", "FBXDBLW01");
                    }
                    xmlDoc = DOMUtil.buildDoc(System.Text.Encoding.UTF8.GetBytes(xmlBuffer.ToString()));
                }

                form.XmlDoc = xmlDoc;
                form.XmlNsResolver = new NamespaceResolver(xmlDoc);
                //CID 0664 //2010.11.02 //End
            }
            //CID 0749 //2011.09.01 //End

            //CID 0749 //2011.09.04 //Begin
            if (ConfigUtil.EnableDigitalSignature())
            {
                //CID 1020 //2011.09.28 //CMD_BUILD_BY_PARAMETERS
                if (form.Command.Equals(JetConstant.CMD_UPDATE_AddSignature) ||
                    form.Command.Equals(JetConstant.CMD_UPDATE_DeleteSignature) ||
                    form.Command.Equals(JetConstant.CMD_UPDATE_Submit) ||
                    form.Command.Equals(JetConstant.CMD_UPDATE_Button) ||
                    form.Command.Equals(JetConstant.CMD_BUILD_BY_PARAMETERS))
                {
                    JetIdCache idCache = new JetIdCache(form.XmlDoc.DocumentElement);
                    DigitalSignatureChecker.CheckSignature(form);
                    idCache.reset();
                }
            }
            //CID 0749 //2011.09.16 //End

			//清空FieldList,这里不是初始化.
			form.FieldList = new ArrayList();

			//CID 0451 //2009.11.09 //Begin
			SchemaPSVI.clearXsiNil( form );
			//CID 0451 //2009.11.09 //End

			FormChangedNodeWorker.checkChangedNode( form );
			//CID 0167 //2008.12.16 //Begin
			ImportParameter.ExecuteOnPostback( form );
			//CID 0167 //2008.12.16 //End
			//CID 0159 //2008.12.03 //Begin
			form.JetContext.OnXmlDocumentReadyEvent( form );
			//CID 0159 //2008.12.03 //End
		}
		
		private static void buildPI(ArrayList piFieldList, StringBuilder xmlBuffer)
		{
			for (int i = 0; i < piFieldList.Count; i++)
			{
				Field piField = (Field) piFieldList[ i ];
				xmlBuffer.Append("<?");
				xmlBuffer.Append(piField.Name);
				xmlBuffer.Append(" ");
				xmlBuffer.Append(piField.Value);
				xmlBuffer.Append("?>");
			}
		}
		
		private static bool buildElementOrText(ArrayList fieldList, int[] coords, StringBuilder xmlBuffer)
		{
			Field field = findElementFieldByCoords(fieldList, coords);
			if (field == null)
			{
				return false;
			}
			
			if (field.Name.Equals(":"))
			{
				xmlBuffer.Append(field.Value);
			}
			else
			{
				xmlBuffer.Append("<");
				xmlBuffer.Append(field.Name);
				xmlBuffer.Append(" ");
				
				ArrayList attrFieldList = findAttributeFields(fieldList, field);
				buildAttributesByFields(attrFieldList, xmlBuffer);
				
				xmlBuffer.Append(">");
				
				xmlBuffer.Append(field.Value);
				
				for (int i = 0; true; i++)
				{
					int[] nextCoords = FieldUtil.nextCoords(coords, i);
					if (!buildElementOrText(fieldList, nextCoords, xmlBuffer))
					{
						break;
					}
				}
				
				xmlBuffer.Append("</");
				xmlBuffer.Append(field.Name);
				xmlBuffer.Append(">");
			}
			
			return true;
		}
		
		private static void  buildAttributesByFields(ArrayList attrFieldList, StringBuilder xmlBuffer)
		{
			for (int i = 0; i < attrFieldList.Count; i++)
			{
				Field attrField = (Field) attrFieldList[ i ];
				StringTokenizer atTokenizer = new StringTokenizer(attrField.Name, "@");
				string attrName = null;
				if (atTokenizer.Count == 2)
				{
					attrName = atTokenizer.NextToken();
					attrName = atTokenizer.NextToken();
				}
				else
				{
					throw new InfoJetException("", "");
				}
				
				xmlBuffer.Append(attrName);
				xmlBuffer.Append("='");
				xmlBuffer.Append(attrField.Value);
				xmlBuffer.Append("'");
				if (i < attrFieldList.Count - 1)
				{
					xmlBuffer.Append(" ");
				}
			}
		}
		
		private static Field findElementFieldByCoords(ArrayList fieldList, int[] coords)
		{
			for (int i = 0; i < fieldList.Count; i++)
			{
				Field field = (Field) fieldList[ i ];
				int[] fieldCoords = field.Coords;
				if (coordsEqual(fieldCoords, coords))
				{
					if (field.Name.IndexOf("@") < 0)
					{
						return field;
					}
				}
			}
			return null;
		}
		
		private static ArrayList findAttributeFields(ArrayList fieldList, Field eleField)
		{
			int[] eleCoords = eleField.Coords;
			string attrPrefix = eleField.Name + "@";
			ArrayList attrFieldList = new ArrayList();
			for (int i = 0; i < fieldList.Count; i++)
			{
				Field field = (Field) fieldList[ i ];
				int[] coords = field.Coords;
				if (coordsEqual(eleCoords, coords))
				{
					if (field.Name.StartsWith(attrPrefix))
					{
						attrFieldList.Add(field);
					}
				}
			}
			return attrFieldList;
		}
		
		private static string strCoords(int[] coords)
		{
			StringBuilder buffer = new StringBuilder();
			for (int i = 0; i < coords.Length; i++)
			{
				buffer.Append(coords[i] + " ");
			}
			return buffer.ToString();
		}
		
		private static bool coordsEqual(int[] coords1, int[] coords2)
		{
			if (coords1.Length == 0 || coords2.Length == 0)
			{
				return false;
			}
			if (coords1.Length != coords2.Length)
			{
				return false;
			}
			for (int i = 0; i < coords1.Length; i++)
			{
				if (coords1[i] != coords2[i])
				{
					return false;
				}
			}
			return true;
		}

		//CID 0352 //2009.07.05 //Begin
		public static void buildNonDirtyXMLDocByFieldList(Form form)
		{
            //CID 0664 //2010.10.06 //Begin
            if (form.Manifest.FormFieldsCacheEnabled)
            {
                throw new InvalidOperationException("InfoJetService.RecoverNonDirtyFormXml() is not supported while FormFieldsCache is enabled.");
            }
            //CID 0664 //2010.10.06 //End

			StringBuilder xmlBuffer = new StringBuilder();
			xmlBuffer.Append("<?xml version='1.0' encoding='UTF-8'?>");
			buildPI(form.PiFieldList, xmlBuffer);
			if (!buildElementOrText(form.FieldList, new int[]{0}, xmlBuffer))
			{
				throw new InfoJetException("Build XML failure by paramters.", "FBXDBLW02");
			}

            XmlDocument xmlDoc = DOMUtil.buildDoc(System.Text.Encoding.UTF8.GetBytes( xmlBuffer.ToString() ) );
            form.XmlDoc = xmlDoc;
			form.XmlNsResolver = new NamespaceResolver(xmlDoc);

			//CID 0451 //2009.11.09 //Begin
			SchemaPSVI.clearXsiNil(form);
			//CID 0451 //2009.11.09 //End

			string valueChangeId = (string) form.ParamTable[JetConstant.XDOC_PARAM_UPDATE_ID];
			if( valueChangeId != null && valueChangeId.Length > 0 )
			{
				form.ValueChangeId = valueChangeId;
			}
			if( form.ValueChangeId != null )
			{
				if( !form.ValueChangeId.StartsWith( "_s_" ) )
				{
					form.ValueChangeNode = DOMUtil.findNodeByJetId( form, form.ValueChangeId );
					if( form.ValueChangeNode != null )
					{
                        //CID 0664 //2010.11.02 //Begin
                        string oldValue = FormUtil.getChangedFieldOldValue(form);
                        //CID 0664 //2010.11.02 //End
						DOMUtil.setNodeValue(form.ValueChangeNode, oldValue);
					}
				}
			}

			//CID 0365 //2009.07.13 //Begin
			string editAction = (string) form.ParamTable[JetConstant.XDOC_PARAM_XML_TO_EDIT_ACTION];
			if( editAction != null && ( editAction.Equals( "xTextList::newItem" ) || editAction.Equals( "xTextList::deleteItem" ) ) )
			{
				string contextIdArray = (string) form.ParamTable[JetConstant.XDOC_PARAM_CONTEXT_ID_ARRAY];
				if( contextIdArray != null )
				{
					ArrayList contextIds = ContextUtil.parseContextIdList(contextIdArray);
					if( contextIds.Count > 0 )
					{
						string textItemId = (string)contextIds[ 0 ];
						XmlNode textItemNode = DOMUtil.findNodeByJetId( form, textItemId );
						if( textItemNode != null )
						{
                            //CID 0664 //2010.11.02 //Begin
                            string oldValue = FormUtil.getChangedFieldOldValue(form);
                            //CID 0664 //2010.11.02 //End
							DOMUtil.setNodeValue(textItemNode, oldValue);
						}
					}
				}
			}
			//CID 0365 //2009.07.13 //End
		}
		//CID 0352 //2009.07.05 //End
	}
}